package chapter1.utils;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public final class ClassUtil {
	private static final Logger LOGGER=LoggerFactory.getLogger(ClassUtil.class);
	
	/**
	 * 获取类加载器
	 * @return
	 */
	public static ClassLoader getClassLoader(){
		ClassLoader cl=Thread.currentThread().getContextClassLoader();
		return cl;
	}
	
	/**
	 * 加载类方法
	 * @param className
	 * @param isInitialized
	 * @return
	 */
   public static Class<?> loadClass(String className,boolean isInitialized){
	   Class<?>  cl=null;
	   try {
		 cl= Class.forName(className,isInitialized,getClassLoader());
	
	   } catch (ClassNotFoundException e) {
		e.printStackTrace();
	  }
		 return cl; 
   }
   
   /**
    * 获取指定包下面的所有类
    * @param packageName
    * @return
    */
   public static Set<Class<?>> getClasser(String packageName){
	   Set<Class<?>> map=new HashSet<Class<?>>();
	  try {
		Enumeration<URL>  urls=  getClassLoader().getResources(packageName.replace(".", "/"));
		
		while(urls.hasMoreElements()){
			URL url=urls.nextElement();
			if(url!=null){
				String protocal=url.getProtocol();
				if(protocal.equals("file")){
					String packagePath=url.getPath().replaceAll("%20", "");
					addClass(map,packagePath,packageName);
				}else if(protocal.equals("jar")){
				   JarURLConnection jarUrl=(JarURLConnection)url.openConnection();
				   if(jarUrl!=null){
					   JarFile jarFile=jarUrl.getJarFile();
					   if(jarFile!=null){
						 Enumeration<JarEntry>  jarEntries=  jarFile.entries();
						 while(jarEntries.hasMoreElements()){
							 JarEntry jarEntry  = jarEntries.nextElement();
							 String jarEntryName=jarEntry.getName();
							 if(jarEntryName.endsWith(".class")){
								 String classname=jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");
								 
								 doAddClass(map,classname);
								 
							 }
							 
							 
						 }
						   
					   }
					   
				   }
				}
				
			}
		}
		
	
	  
	  } catch (IOException e) {
		e.printStackTrace();
	}
	   return null;
   }
   
   /**
    * 把class加到Set容器中
    * 
    * @param clSet
    * @param packagePath
    * @param packageName
    */
   public static void addClass(Set<Class<?>> clSet,String packagePath,String packageName){
	   File[] files=new File(packagePath).listFiles(new FileFilter() {
		
		@Override
		public boolean accept(File pathname) {
			
			return (pathname.isFile()&&pathname.getName().endsWith(".class"))||pathname.isDirectory();
		}
	});
	   for(File file:files){
		    String fileName=file.getName();
		    if(file.isFile()){
		    	String className=fileName.substring(0,fileName.lastIndexOf("."));
		    	if(className!=null&&"".equals(className)){
		    		className=packagePath+"."+className;
		    	}
		    	doAddClass(clSet,className);	
		    }else{
		    	String subPackagePath=fileName;
		    	if(subPackagePath!=null&&"".equals(subPackagePath)){
		    		subPackagePath=packagePath+"/"+subPackagePath;
		    	}
		    	packageName=packageName+"."+fileName;
		    	addClass(clSet,subPackagePath,packageName);
		    	
		    	
		    }
	   }
   }
   
   public static void doAddClass(Set<Class<?>> clset,String className){
	   Class<?> cl=loadClass(className,false);
	   clset.add(cl);
	   
	   
   }
   
   public static void main(String[] args) throws IOException{
	   Enumeration<URL>  urls=  getClassLoader().getResources("chapter1.utils".replace(".", "/"));
	   while(urls.hasMoreElements()){
			URL url=urls.nextElement();
			System.out.println(url);
			System.out.println(url.getPath());
	   }	
   }

}
